<!-- 添加/编辑 培训 -->

<template>
  <DialogLayout ref="dialogRef" method="POST" path="/dev-api/oa/headcount" @submited="handlerDialogSubmited">
    <el-form-item label="培训名称" prop="name">
      <el-input v-model="dialogForm.name" autocomplete="off" />
    </el-form-item>
    <el-form-item label="培训类别" prop="trainingCategory">
      <el-select v-model="dialogForm.trainingCategory" clearable>
        <el-option class="radio-option-cell" v-for="(item, idx) in useTrainingCategoryStore().trainingCategory" :key="idx" :value="item.dictValue" :label="item.dictLabel" />
      </el-select>
    </el-form-item>
    <el-form-item label="培训对象" prop="deptIds">
      <el-cascader :options="deptList" :props="deptProps" v-model="dialogForm.deptIds" style="width: 100%" @change="handleChangeDept" />
    </el-form-item>
    <el-form-item label="讲师姓名" prop="teacherId">
      <el-select v-model="dialogForm.teacherId" filterable clearable reserve-keyword placeholder="" @change="handlerChangeTeacher" :loading="loading" style="width: 100%">
        <el-option v-for="item in teacherOptions" :key="item.userId" :label="item.nickName + '-' + item.userName" :value="item.userId" />
      </el-select>
    </el-form-item>
    <el-form-item label="预计培训日期" prop="trainingDate" label-width="126px">
      <el-date-picker v-model="dialogForm.trainingDate" type="date" style="width: 100%" format="YYYY-MM-DD" />
    </el-form-item>
    <el-form-item label="培训课时" prop="durationTime">
      <el-input-number v-model="dialogForm.durationTime" :min="1" :max="10000" controls-position="right" />
    </el-form-item>
    <el-form-item label="培训地点" prop="place">
      <el-input v-model="dialogForm.place" autocomplete="off" />
    </el-form-item>
    <el-form-item label="培训方式 " prop="manner">
      <el-input v-model="dialogForm.manner" autocomplete="off" :autosize="{ minRows: 4, maxRows: 8 }" type="textarea" placeholder="" />
    </el-form-item>
    <el-divider content-position="left">
      <el-checkbox v-model="isChecked">实施行情况</el-checkbox>
    </el-divider>
    <Transition name="fade" mode="out-in">
      <div v-if="isChecked">
        <el-form-item label="实际培训时间" prop="actualTrainingDate" label-width="124px">
          <el-date-picker v-model="dialogForm.actualTrainingDate" type="date" style="width: 100%" format="YYYY-MM-DD" />
        </el-form-item>
        <el-form-item label="实际参与人数" prop="actualJoinUser" label-width="124px">
          <el-input-number v-model="dialogForm.actualJoinUser" :min="0" :max="10000" controls-position="right" />
        </el-form-item>
        <el-form-item label="培训人*时" prop="userTime" label-width="124px">
          <el-input-number v-model="dialogForm.userTime" :min="0" :max="10000" controls-position="right" />
        </el-form-item>
        <el-form-item label="备注" label-width="124px">
          <el-input v-model="dialogForm.remark" autocomplete="off" :autosize="{ minRows: 4, maxRows: 8 }" type="textarea" placeholder="" />
        </el-form-item>
      </div>
    </Transition>
  </DialogLayout>
</template>
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
import DialogLayout from '../../layout/DialogLayout.vue'
import { FormRules } from 'element-plus'
import { useDeptStore, useTrainingCategoryStore } from '../../stores'
import * as utils from '../../utils'
import { ElMessage } from 'element-plus'
import api from '../../api'

const emits = defineEmits(['submited'])
const deptProps = ref({ label: 'deptName', value: 'deptId' })
const deptList = ref(useDeptStore().getAllState())
const dialogRef = ref<InstanceType<typeof DialogLayout>>()
const teacherOptions = ref<any[]>([])
const loading = ref(false)
const isChecked = ref(false)

const dialogForm = reactive({
  id: null,
  name: '',
  deptIds: [] as number[],
  deptId: -1,
  deptName: '',
  trainingDate: '',

  durationTime: 1,
  place: '',
  teacherId: null,
  teacherName: '',
  manner: '',
  trainingCategory: null,

  actualTrainingDate: null,
  actualJoinUser: 0,
  userTime: 0,
  remark: '',
})

const rules = reactive<FormRules>({
  name: [{ required: true, message: '请输入资产名称', trigger: ['blur', 'change'] }],
  deptIds: [{ required: true, message: '请选择部门', trigger: ['blur', 'change'] }],
  teacherId: [{ required: true, message: '请选择讲师', trigger: ['blur', 'change'] }],
  trainingDate: [{ required: true, message: '请选择培训日期', trigger: ['blur', 'change'] }],
  durationTime: [
    { required: true, message: '请输入培训课时', trigger: ['blur', 'change'] },
    { pattern: /^\d+(\.\d+)?$/, message: '培训课时必须为数字（可以是小数）', trigger: ['blur', 'change'] },
  ],
  place: [{ required: true, message: '请输入培训地点', trigger: ['blur', 'change'] }],
  manner: [{ required: true, message: '请输入培训方式', trigger: ['blur', 'change'] }],
  trainingCategory: [{ required: true, message: '请选择培训类别', trigger: ['blur', 'change'] }],
})
// 通用验证函数：验证是否为数字且大于 0
const validateNumberGreaterThanZero = (fieldName: string, value: any, callback: any) => {
  if (!value) {
    callback(new Error(`请输入${fieldName}`))
  } else if (!/^\d+(\.\d+)?$/.test(value)) {
    callback(new Error(`${fieldName}必须为数字`))
  } else if (Number(value) <= 0) {
    callback(new Error(`${fieldName}必须大于 0`))
  } else {
    callback()
  }
}

// 实际参与人数的验证
const validateActualJoinUser = (_: any, value: any, callback: any) => {
  validateNumberGreaterThanZero('实际参与人数', value, callback)
}

// 培训人*时的验证
const validateUserTime = (_: any, value: any, callback: any) => {
  validateNumberGreaterThanZero('培训人*时', value, callback)
}
watch(
  () => isChecked.value,
  (newValue) => {
    if (newValue) {
      rules.actualTrainingDate = [{ required: true, message: '请选择实际培训日期', trigger: ['blur', 'change'] }]
      rules.actualJoinUser = [{ required: true, validator: validateActualJoinUser, trigger: ['blur', 'change'] }]
      rules.userTime = [{ required: true, validator: validateUserTime, trigger: ['blur', 'change'] }]
    } else {
      rules.actualTrainingDate = []
      rules.actualJoinUser = []
      rules.userTime = []
    }
  }
)

const openDialog = async (val: any) => {
  let dialogTitle = '添加培训'
  isChecked.value = false

  if (val.id) {
    dialogTitle = '编辑培训'
    dialogForm.id = val.id
    dialogForm.name = val.name
    dialogForm.trainingDate = val.trainingDate
    dialogForm.teacherId = val.teacherId
    dialogForm.teacherName = val.teacherName
    dialogForm.durationTime = val.durationTime
    dialogForm.place = val.place
    dialogForm.deptId = val.deptId
    dialogForm.deptName = val.deptName
    dialogForm.manner = val.manner
    dialogForm.trainingCategory = val.trainingCategory.toString()
    dialogForm.actualTrainingDate = val.actualTrainingDate
    dialogForm.actualJoinUser = val.actualJoinUser
    dialogForm.userTime = val.userTime
    dialogForm.remark = val.remark
    const deptItem = useDeptStore().deptList.find((item: any) => item.deptId === dialogForm.deptId)
    // console.log('openDialog deptItem', deptItem.ancestors, dialogForm.deptId)
    dialogForm.deptIds = [...deptItem.ancestors.split(',').map(Number), dialogForm.deptId].filter((item) => item !== 0)
    await getUserList(dialogForm.deptIds[dialogForm.deptIds.length - 1])
    // teacherOptions.value.unshift({ userId: dialogForm.userId, userName: dialogForm.userName, nickName: dialogForm.userNick })
    if (val.actualTrainingDate || val.actualJoinUser || val.userTime || val.remark) {
      isChecked.value = true
    }
  } else {
    dialogForm.id = null
    dialogForm.name = val.name
    dialogForm.trainingDate = ''
    dialogForm.teacherId = null
    dialogForm.teacherName = ''
    dialogForm.durationTime = 1
    dialogForm.place = ''
    dialogForm.deptName = ''
    dialogForm.deptId = -1
    dialogForm.deptName = ''
    dialogForm.manner = ''
    dialogForm.trainingCategory = null
    dialogForm.actualTrainingDate = null
    dialogForm.actualJoinUser = 0
    dialogForm.userTime = 0
    dialogForm.remark = ''
  }
  dialogRef.value?.openDialog({
    title: dialogTitle,
    class: 'dialog-add-training',
    form: dialogForm,
    rules: rules,
    submitFunction: async (callback: Function) => {
      dialogForm.deptId = dialogForm.deptIds[dialogForm.deptIds.length - 1]
      const deptItem = useDeptStore().deptList.find((item: any) => item.deptId === dialogForm.deptId)
      dialogForm.deptName = deptItem.deptName
      dialogForm.trainingDate = utils.formatDate(new Date(dialogForm.trainingDate), 'yyyy-MM-dd')
      let res: any = null
      let messageText = ''
      const { actualTrainingDate, actualJoinUser, userTime, remark, ...rest } = dialogForm
      const newRest = isChecked.value ? { ...dialogForm } : rest
      if (dialogForm.id) {
        res = await api.Training.update({ ...newRest })
        messageText = '修改'
      } else {
        res = await api.Training.add({ ...newRest })
        messageText = '添加'
      }
      console.log('submitFunction  res', res)
      if (res.code == 200) {
        ElMessage({
          message: `${messageText}成功！`,
          grouping: true,
          type: 'success',
        })
      } else {
        ElMessage({
          message: `${messageText}失败！`,
          grouping: true,
          type: 'error',
        })
      }
      emits('submited')
      await callback()
    },
  })
}

const handlerDialogSubmited = (data: any) => {
  emits('submited', data)
}

/**
 * 处理部门选择变化
 *
 * @param value 当前选中的部门值
 */
const handleChangeDept = async (value: any) => {
  dialogForm.teacherId = null
  teacherOptions.value = []
  await getUserList(value[value.length - 1])
}
const getUserList = async (deptId: number | null = 0) => {
  const params = {
    pageSize: 999999,
  }
  if (deptId && deptId > 0) {
    Object.assign(params, { deptId })
  }
  teacherOptions.value = await api.Users.getAll(params)
}
const handlerChangeTeacher = async (value: any) => {
  dialogForm.teacherName = ''
  teacherOptions.value.find((item: any) => {
    if (item.userId === value) {
      dialogForm.teacherName = item.nickName
    }
  })
}
defineExpose({
  openDialog,
})
</script>
<style lang="scss" scoped>
/* 定义 fade 动画 */
.fade-enter-active {
  transition: all 0.5s ease-out;
}
.fade-leave-active {
  transition: all 0.5s cubic-bezier(1, 0.5, 0.8, 1);
}

.fade-enter-from,
.fade-leave-to {
  transform: translateY(-20px);
  opacity: 0;
}
</style>
